﻿using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using KJFrame.Core.Rpc.Client.Internal;
using KJFrame.Core.Rpc.Protocol;

namespace KJFrame.Core.Rpc.Client
{
    public static class RpcClientFactory
    {
        private static readonly ConcurrentDictionary<Type, TypeInfo> _proxyClientCache = new ConcurrentDictionary<Type, TypeInfo>();
        private static readonly GrpcClientTypeBuilder _builder = new GrpcClientTypeBuilder();


        /// <summary>
        /// 创建服务
        /// </summary>
        /// <typeparam name="TService"></typeparam>
        /// <param name="rpcChannel"></param>
        /// <returns></returns>
        public static TService Create<TService>(IRpcChannel rpcChannel)
            where TService : class, IRpcService
        {
            var serviceType = typeof(TService);
            if (!_proxyClientCache.ContainsKey(serviceType) || !_proxyClientCache.TryGetValue(serviceType, out var serviceInstanceTypeInfo))
            {
                serviceInstanceTypeInfo = _builder.Create<TService>();
                _proxyClientCache.TryAdd(serviceType, serviceInstanceTypeInfo);
            }

            var instance = Activator.CreateInstance(serviceInstanceTypeInfo, rpcChannel);
            return (TService)instance;
        }

        public static object Create(IRpcChannel rpcChannel, Type serviceType)
        {
            if (!_proxyClientCache.ContainsKey(serviceType) || !_proxyClientCache.TryGetValue(serviceType, out var serviceInstanceTypeInfo))
            {
                serviceInstanceTypeInfo = _builder.Create(serviceType);
                _proxyClientCache.TryAdd(serviceType, serviceInstanceTypeInfo);
            }
            var instance = Activator.CreateInstance(serviceInstanceTypeInfo, rpcChannel);
            return instance;
        }
    }
}
